package cn.zglbk.network.gateway;

import cn.zglbk.common.GameMessageService;
import cn.zglbk.common.concurrent.GameEventExecutorGroup;
import cn.zglbk.config.GameChannelConfig;
import cn.zglbk.network.channel.GameChannelInitializer;
import cn.zglbk.network.channel.GameMessageEventDispatchService;
import cn.zglbk.network.channel.IMessageSendFactory;
import cn.zglbk.network.context.GameGatewayMessageSendFactory;
import cn.zglbk.network.gateway.handler.codec.GameMessageInnerDecoder;
import cn.zglbk.network.param.EnumMesasageType;
import cn.zglbk.network.param.GameMessageHeader;
import cn.zglbk.network.param.GameMessagePackage;
import cn.zglbk.network.param.IGameMessage;
import cn.zglbk.network.rpc.GameRpcService;
import cn.zglbk.utils.SpringUtils;
import io.netty.channel.ChannelHandlerContext;
import io.netty.util.concurrent.DefaultEventExecutorGroup;
import io.netty.util.concurrent.DefaultThreadFactory;
import io.netty.util.concurrent.EventExecutorGroup;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;

/**
 * 用于接收网关消息，并分发消息到业务中。
 *
 * @ClassName: GatewayMessageConsumerService
 * @Description: TODO
 * @author: wgs
 * @date: 2019年6月1日 下午8:27:39
 */
@Service("gatewayMessageConsumerService")
public class GatewayMessageConsumerService {
    /**
     * 默认实现的消息发送接口，GameChannel返回的消息通过此接口发送到kafka中
     */
    private IMessageSendFactory gameGatewayMessageSendFactory;
    //    private GameRpcService gameRpcSendFactory;
    private Logger logger = LoggerFactory.getLogger(GatewayMessageConsumerService.class);
    /**
     * GameChannel的一些配置信息
     */
    @Autowired
    private GameChannelConfig serverConfig;
    /**
     * 消息管理类，负责管理根据消息id，获取对应的消息类实例
     */
    @Autowired
    private GameMessageService gameMessageService;
    @Autowired
    private ChannelService channelService;
    /**
     * 消息事件分类发，负责将用户的消息发到相应的GameChannel之中。
     */
    private GameMessageEventDispatchService gameChannelService;
    /**
     * 业务处理的线程池
     */
    private GameEventExecutorGroup workerGroup;
    //    private EventExecutorGroup rpcWorkerGroup = new DefaultEventExecutorGroup(1);
    @Autowired
    private ApplicationContext context;

    public void setMessageSendFactory(IMessageSendFactory messageSendFactory) {
        this.gameGatewayMessageSendFactory = messageSendFactory;
    }

    public GameMessageEventDispatchService getGameMessageEventDispatchService() {
        return this.gameChannelService;
    }

    public void start(GameChannelInitializer gameChannelInitializer) {
        workerGroup = new GameEventExecutorGroup(serverConfig.getWorkerThreads(),new DefaultThreadFactory("玩家线程池："));
        gameGatewayMessageSendFactory = new GameGatewayMessageSendFactory(channelService);
//        gameRpcSendFactory = new GameRpcService(serverConfig.getRpcRequestGameMessageTopic(),serverConfig.getRpcResponseGameMessageTopic(),localServerId, null);
        gameChannelService = new GameMessageEventDispatchService(context, workerGroup, gameGatewayMessageSendFactory, null, gameChannelInitializer);
//        workerGroup = new GameEventExecutorGroup(serverConfig.getWorkerThreads());
    }

    public static void recieve(GameMessagePackage msg) {
        GatewayMessageConsumerService application = SpringUtils.getBean("gatewayMessageConsumerService", GatewayMessageConsumerService.class);
        if(application != null){
            application.consume(msg);
        }
    }

    private void consume(GameMessagePackage record) {
//        IGameMessage gameMessage = this.getGameMessage(EnumMesasageType.REQUEST, record);
//        GameMessageHeader header = gameMessage.getHeader();
        //gameChannelService在main启动的时候启动
        gameChannelService.fireReadMessage(record.getHeader().getPlayerId(), record);
    }

    private IGameMessage getGameMessage(EnumMesasageType mesasageType, byte[] data) {
        GameMessagePackage gameMessagePackage = GameMessageInnerDecoder.readGameMessagePackage(data);
        logger.debug("收到{}消息：{}", mesasageType, gameMessagePackage.getHeader());
        return getGameMessage(mesasageType,gameMessagePackage);
    }
    private IGameMessage getGameMessage(EnumMesasageType mesasageType, GameMessagePackage gameMessagePackage ){
        GameMessageHeader header = gameMessagePackage.getHeader();
        IGameMessage gameMessage = gameMessageService.getMessageInstance(mesasageType, header.getMessageId());
        gameMessage.read(gameMessagePackage.getBody());
        gameMessage.setHeader(header);
        gameMessage.getHeader().setMesasageType(mesasageType);
        return gameMessage;
    }

}
